package com.itlin.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itlin.bean.*;
import com.itlin.common.CustomException;
import com.itlin.dao.SetmealDao;
import com.itlin.dao.SetmealDishDao;
import com.itlin.dto.SetmealDto;
import com.itlin.service.CategoryService;
import com.itlin.service.SetmealDishService;
import com.itlin.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author 所谓伊人
 * @date 2022/3/24 - 20:19
 */
@Transactional
@Service
public class SetmealServiceIpl implements SetmealService {

    @Autowired
    private SetmealDao dao;

    @Autowired
    private SetmealDishDao setmealDishDao;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    @Override
    public int countByCid(long cid) {

        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();

        qw.eq(Setmeal::getCategoryId,cid);

        return dao.selectCount(qw);
    }

    @Override
    public int add(SetmealDto setmealDto) {

        int row = dao.insert(setmealDto);

        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();

        if (row > 0) {
            int row2 = 0;

            for (SetmealDish setmealDish : setmealDishes) {

                setmealDish.setSetmealId(setmealDto.getId());

                row2 += setmealDishService.add(setmealDish);
            }

            return row2 == setmealDishes.size() ? 1 : 0;
        }

        return row;
    }

    /**
     * 分页查询
     *  1. 分页查询要考虑的事情还是比较多的：
     *      1.1 除了要返回基本的分页数据之外，还要考虑页面显示分类名称的问题
     *      1.2 在套餐表里面并不保存这个套餐属于哪一种分类，所以需要去查询分类表
     *      1.3 为了确保后续在页面上做更新的时候，能够完整的回显套餐的数据，所以也需要去把
     *          套餐包含哪些菜品的数据给查询出来。！【不讲！】
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<SetmealDto> findPage(PageParam pageParam) {

        //1. 定义条件对象
        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();

        //1.1 插入搜索条件
        qw.like(pageParam.getName() != null , Setmeal::getName , pageParam.getName());

        //2. 定义查询具体多少页，每页多少条
        IPage<Setmeal> p = new Page<>(pageParam.getPage() , pageParam.getPageSize());

        //3. 执行查询 查询出来的套餐数据，并不包含分类的名称，所以要接着去查询分类表，得到分类的名称
        IPage<Setmeal> page = dao.selectPage(p, qw);

        //4. 遍历得到每一个套餐数据
        List<SetmealDto> list = page.getRecords() // 得到集合数据
                .stream() //转化流
                .map( s -> { //s即代表遍历出来的每一个套餐对象，需要映射成一个新的对象SetmealDto
                    //1. 构建一个SetmealDto
                    SetmealDto dto = new SetmealDto();

                    //2. 把原始的套餐数据拷贝到dto身上
                    BeanUtils.copyProperties(s , dto);

                    //3. 拿着套餐的分类id去把分类的数据给查询出来
                    Category c = categoryService.findById(s.getCategoryId());

                    //4. 给SetmealDto 设置分类的名字
                    dto.setCategoryName(c.getName());

                    //5. 返回SetmealDto
                    return dto;
                }).collect(Collectors.toList());

        //5. 构建一个IPage对象
        IPage<SetmealDto> dtoIPage = new Page<>();

        //5.1 设置总记录数
        dtoIPage.setTotal(page.getTotal());

        //5.2 设置当前页的集合数据
        dtoIPage.setRecords(list);

        return dtoIPage;
    }

    @Override
    public int delete(List<Long> ids) {// select * from setmeal where id in (1,2,3);

        //1. 查询数据库，看看有没有哪个套餐属于启售状态，如果有，那么禁止删除
        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();

        //2. 设置条件...  select * from setmeal where id in (1,2,3);
        qw.in(Setmeal::getId , ids);

        //3. 设置状态的条件 select count(*) from setmeal where status = 启售状态 and  id in (1,2,3);
        qw.eq(Setmeal::getStatus , 1);

        //4. 执行查询
        int count = dao.selectCount(qw);

        //5. 如果查询出来的数量 > 0 ，那么认为是禁止删除的。
        if(count > 0 ){
            throw  new CustomException("套餐处于启售状态，禁止删除！");
        }

        //6. 如果上面的if语句没有进去，即表示可以删除。
        int row = dao.deleteBatchIds(ids);

        //7. 只有当套餐能够删除了之后，再去执行套餐菜品表的删除操作
        if(row > 0 ){ // 10 ,11 ,12

            setmealDishService.delete(ids);

        }

        return row;
    }

    @Override
    public List<Setmeal> findByCategoryId(long categoryId, Integer status) {
        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();

        qw.eq(Setmeal::getCategoryId, categoryId);

        qw.eq(status != null, Setmeal::getStatus, status);

        return dao.selectList(qw);
    }

    @Override
    public int updateStatus(Setmeal setmeal,List<Long> ids){
        LambdaQueryWrapper<Setmeal> lq=new LambdaQueryWrapper<>();
        lq.in(Setmeal::getId,ids);
        int row = dao.update(setmeal,lq);
        return row;
    }

//    套餐数据回显
    @Override
    public SetmealDto show(Long id) {
        SetmealDto setmealDto = new SetmealDto();
//        查找套餐
        LambdaQueryWrapper<Setmeal> lq=new LambdaQueryWrapper<>();
        lq.eq(Setmeal::getId,id);
        Setmeal setmeal = dao.selectOne(lq);
//        查找套餐中的菜
        LambdaQueryWrapper<SetmealDish> lq2=new LambdaQueryWrapper<>();
        lq2.eq(SetmealDish::getSetmealId,id);
        List<SetmealDish> list = setmealDishDao.selectList(lq2);
//        装配Dto
        if (setmeal!=null){
            BeanUtils.copyProperties(setmeal,setmealDto);
            setmealDto.setSetmealDishes(list);
            return setmealDto;}
        else return setmealDto;
    }

//    修改数据

    @Override
    public int updateSeatmeal(SetmealDto setmealDto) {
        int i = dao.updateById(setmealDto);
        if (i>0){
            int row=0;
            LambdaQueryWrapper<SetmealDish> lq=new LambdaQueryWrapper<>();
            lq.eq(SetmealDish::getSetmealId,setmealDto.getId());
            setmealDishDao.delete(lq);
            List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
            for (SetmealDish setmealDish:setmealDishes) {
                setmealDish.setSetmealId(setmealDto.getId());
                row+= setmealDishDao.insert(setmealDish);
            }
            if (row==setmealDishes.size()){
                return row;
            }
        }
        return 0;
    }
}
